package com.zhuoyue.web.controller.exception;


import com.zhuoyue.common.constant.ResultCode;
import com.zhuoyue.common.dto.ControllerResult;

import com.zhuoyue.common.exception.ZyServerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;


/**
 * @author wjming
 */
@RestControllerAdvice
@ResponseBody
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ExceptionAdv {
    @ExceptionHandler(RuntimeException.class)
    public ControllerResult securityExceptionHandler(RuntimeException ex) {
        log.warn("RuntimeException -> [{}]", ex.getMessage());
        if (ex instanceof IllegalArgumentException) {
            return ControllerResult.toParamFail(ex.getMessage());
        }
        if (ex instanceof ConstraintViolationException) {
            return ControllerResult.toParamFail(ex.getMessage().split(":")[1]);
        }
        if (ex instanceof SecurityException) {
            return ControllerResult.toTokenExpiret("验证异常请重新登陆");
        }
        if (ex instanceof ZyServerException) {
            switch (((ZyServerException) ex).getCode()) {
                case 0:
                case 1:
                case 4:
                case 7:
                case 8:
                    return ControllerResult.toParamFail(ex.getMessage());
                case 2:
                    return ControllerResult.toNoDataFail(ex.getMessage());
                //短信验证码异常
                case 6:
                    //redis
                case 10:
                    return ControllerResult.toOtherFail(ex.getMessage(), ResultCode.WINXIN_NO_DATA);
                //成功抛出的请求
                case 11:
                    return ControllerResult.toReturnMessageSuccess(ex.getMessage());
                //短信验证码发送失败
                case 5:
                case 12:
                case 13:
                case 14:
                case 15:
                    //快速登陆错误
                case 55555:
                    return ControllerResult.toFail(ex.getMessage());

                default:
                    break;
            }

        }

        return ControllerResult.toSysErrorFail("系统异常");
    }


    /**
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ControllerResult methodArgumentNotValidHandler(MethodArgumentNotValidException ex) {
        log.error("MethodArgumentNotValidHandler -> [{}]", ex.getMessage());
        //按需重新封装需要返回的错误信息
        List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
        //解析原错误信息，封装后返回，此处返回非法的字段名称，原始值，错误信息
        for (FieldError error : ex.getBindingResult().getFieldErrors()) {
            ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
            invalidArgument.setDefaultMessage(error.getDefaultMessage());
            invalidArgument.setField(error.getField());
            invalidArgument.setRejectedValue(error.getRejectedValue());
            invalidArguments.add(invalidArgument);
        }
        return ControllerResult.toParamFail(invalidArguments.get(0).getDefaultMessage());

    }

    /**
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public ControllerResult missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException ex) {
        log.error("MissingServletRequestParameterExceptionHandler -> [{}]", ex.getMessage());
        return ControllerResult.toParamFail(ex.getParameterName() + "不能为空");
    }

    /**
     * 空指针错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    public ControllerResult nullPointerException(NullPointerException ex) {
        log.error("NullPointerException -> [{}]", ex.getMessage());
        return ControllerResult.toParamFail("数据错误");
    }

}
